{*******************************************************************************
* The contents of this file are used with permission, subject to the Mozilla   *
* Public License Version 1.1 (the "License"); you may not use this file except *
* in compliance with the License. You may obtain a copy of the License at      *
* http://www.mozilla.org/MPL/                                                  *
*                                                                              *
* Software distributed under the License is distributed on an "AS IS" basis,   *
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for *
* the specific language governing rights and limitations under the License.    *
*                                                                              *
* The Original Code is distributed as part of the "mediate" product and is     *
* Copyright (C) @home media limited. All Rights Reserved.                      *
*                                                                              *
* Email: support@athomemedia.co.uk                                             *
* Web:   http://www.athomemedia.co.uk                                          *
*******************************************************************************}

unit Settings;

interface

uses Classes, MetaConsts;

type
  TAHMSettingsManager = class
  private
  protected
    procedure LoadAllSettings;
    procedure SaveAllSettings;
    procedure LoadDisplaySettings;
    procedure LoadPositionSettings;
    procedure LoadAudioSettings;
    procedure LoadGeneralSettings;
    procedure LoadSlideshowSettings;
    procedure LoadThemeSettings;
    procedure LoadVisualisationSettings;
    procedure LoadEqualiserSettings;
    procedure LoadMusicSettings;
    procedure SaveDisplaySettings;
    procedure SavePositionSettings;
    procedure SaveAudioSettings;
    procedure SaveGeneralSettings;
    procedure SaveSlideshowSettings;
    procedure SaveThemeSettings;
    procedure SaveVisualisationSettings;
    procedure SaveEqualiserSettings;
    procedure SaveMusicSettings;
  public
    procedure LoadMetaData(GroupName: String);
    procedure SaveMetaData(GroupName: String);
  end;

implementation

uses SysUtils, ApplicationManager, UIObjects, Screen, Preferences, Languages,
     Actions, Equaliser, Logging, MetaData;

procedure TAHMSettingsManager.LoadMetaData(GroupName: String);
begin
  // Is this a supported group of meta data values?
  if GroupName = META_SETTINGS then LoadAllSettings
  else if GroupName = META_DISPLAY then LoadDisplaySettings
  else if GroupName = META_POSITION then LoadPositionSettings
  else if GroupName = META_AUDIO then LoadAudioSettings
  else if GroupName = META_GENERAL then LoadGeneralSettings
  else if GroupName = META_SLIDESHOW then LoadSlideshowSettings
  else if GroupName = META_THEME_SETTINGS then LoadThemeSettings
  else if GroupName = META_VISUALISATION then LoadVisualisationSettings
  else if GroupName = META_EQUALISER then LoadEqualiserSettings
  else if GroupName = META_MUSIC then LoadMusicSettings
  else LogWarn('Request to load unknown meta data values group: ' + GroupName);
end;

procedure TAHMSettingsManager.SaveMetaData(GroupName: String);
begin
  // Is this a supported group of meta data values?
  if GroupName = META_SETTINGS then SaveAllSettings
  else if GroupName = META_DISPLAY then SaveDisplaySettings
  else if GroupName = META_POSITION then SavePositionSettings
  else if GroupName = META_AUDIO then SaveAudioSettings
  else if GroupName = META_GENERAL then SaveGeneralSettings
  else if GroupName = META_SLIDESHOW then SaveSlideshowSettings
  else if GroupName = META_THEME_SETTINGS then SaveThemeSettings
  else if GroupName = META_VISUALISATION then SaveVisualisationSettings
  else if GroupName = META_EQUALISER then SaveEqualiserSettings
  else if GroupName = META_MUSIC then SaveMusicSettings
  else LogWarn('Request to save unknown meta data values group: ' + GroupName);
end;

procedure TAHMSettingsManager.LoadAllSettings;
begin
  // Invoke each of our individual settings methods below
  LoadDisplaySettings;
  LoadPositionSettings;
  LoadAudioSettings;
  LoadGeneralSettings;
  LoadSlideshowSettings;
  LoadThemeSettings;
  LoadVisualisationSettings;
  LoadEqualiserSettings;
  LoadMusicSettings;
end;

procedure TAHMSettingsManager.SaveAllSettings;
begin
  // Invoke each of our individual settings methods below
  SaveDisplaySettings;
  SavePositionSettings;
  SaveAudioSettings;
  SaveGeneralSettings;
  SaveSlideshowSettings;
  SaveThemeSettings;
  SaveVisualisationSettings;
  SaveEqualiserSettings;
  SaveMusicSettings;
end;

procedure TAHMSettingsManager.LoadDisplaySettings;
var
  Mode: TAHMDisplayMode;
  Values: TAHMMetaData;
  Prefs: TAHMPrefsManager;
  i: Integer;
begin
  // Load display settings into meta data manager
  Prefs := ApplicationManagerInstance.PreferencesManager;
  Values := TAHMMetaData.Create;
  try
    // Add list of supported display modes and current mode
    with ScreenInstance.DisplayModes do
    begin
      for i := 0 to Pred(Count) do
      begin
        Mode := GetDisplayMode(i);
        Values.AddValue(META_SCREENSIZES + META_SEP + IntToStr(i), Mode.AsString);
        if (Mode.Width = Prefs.ScreenWidth) and (Mode.Height = Prefs.ScreenHeight) then
          Values.AddValue(META_SCREENSIZE, IntToStr(i));
      end;
    end;

    // Add list of screensaver delays - zero padded so sorted in right order
    Values.AddValue(META_SCREENSAVERS + META_SEP + '0000', META_MARKER + META_TEXT_BEG + 'system.screensaver.off' + META_TEXT_END);
    Values.AddValue(META_SCREENSAVERS + META_SEP + '0060', '1 ' + META_MARKER + META_TEXT_BEG + 'system.screensaver.minute' + META_TEXT_END);
    Values.AddValue(META_SCREENSAVERS + META_SEP + '0120', '2 ' + META_MARKER + META_TEXT_BEG + 'system.screensaver.minutes' + META_TEXT_END);
    Values.AddValue(META_SCREENSAVERS + META_SEP + '0300', '5 ' + META_MARKER + META_TEXT_BEG + 'system.screensaver.minutes' + META_TEXT_END);
    Values.AddValue(META_SCREENSAVERS + META_SEP + '0600', '10 ' + META_MARKER + META_TEXT_BEG + 'system.screensaver.minutes' + META_TEXT_END);
    Values.AddValue(META_SCREENSAVERS + META_SEP + '1800', '30 ' + META_MARKER + META_TEXT_BEG + 'system.screensaver.minutes' + META_TEXT_END);
    Values.AddValue(META_SCREENSAVERS + META_SEP + '3600', '1 ' + META_MARKER + META_TEXT_BEG + 'system.screensaver.hour' + META_TEXT_END);
    Values.AddValue(META_SCREENSAVERS + META_SEP + '7200', '2 ' + META_MARKER + META_TEXT_BEG + 'system.screensaver.hours' + META_TEXT_END);
    Values.AddValue(META_SCREENSAVER, Format('%.4d', [Prefs.ScreenSaverDelay]));

    // Add list of video frame throttles - zero padded so sorted in right order
    Values.AddValue(META_VIDEOTHROTTLES + META_SEP + '00', META_MARKER + META_TEXT_BEG + 'system.videothrottle.off' + META_TEXT_END);
    Values.AddValue(META_VIDEOTHROTTLES + META_SEP + '01', META_MARKER + META_TEXT_BEG + 'system.videothrottle.low' + META_TEXT_END);
    Values.AddValue(META_VIDEOTHROTTLES + META_SEP + '02', META_MARKER + META_TEXT_BEG + 'system.videothrottle.medium' + META_TEXT_END);
    Values.AddValue(META_VIDEOTHROTTLES + META_SEP + '05', META_MARKER + META_TEXT_BEG + 'system.videothrottle.high' + META_TEXT_END);
    Values.AddValue(META_VIDEOTHROTTLE, Format('%.2d', [Prefs.VideoThrottle]));

    // Fullscreen setting is simple boolean flag
    Values.AddValue(META_FULLSCREEN, Prefs.FullScreen);

    Values.Apply;
  finally
    Values.Free;
  end;
end;

procedure TAHMSettingsManager.LoadPositionSettings;
var
  Values: TAHMMetaData;
  Prefs: TAHMPrefsManager;
begin
  // Load position/scale settings into meta data manager
  Prefs := ApplicationManagerInstance.PreferencesManager;
  Values := TAHMMetaData.Create;
  try
    Values.AddValue(META_POS_XOFFSET, Round((Prefs.ScreenXOffset + 0.5) * Prefs.ScreenWidth));
    Values.AddValue(META_POS_YOFFSET, Round((Prefs.ScreenYOffset + 0.5) * Prefs.ScreenHeight));
    Values.AddValue(META_POS_XSCALE, Round((Prefs.ScreenXScale - 0.5) * Prefs.ScreenWidth));
    Values.AddValue(META_POS_YSCALE, Round((Prefs.ScreenYScale - 0.5) * Prefs.ScreenHeight));

    // Add groups to allow +/- half a screen offsetting
    Values.AddValue(META_POS_XOFFSETS, Prefs.ScreenWidth);
    Values.AddValue(META_POS_YOFFSETS, Prefs.ScreenHeight);

    // Add groups to allow half to double size scaling
    Values.AddValue(META_POS_XSCALES, (3 * Prefs.ScreenWidth) div 2);
    Values.AddValue(META_POS_YSCALES, (3 * Prefs.ScreenHeight) div 2);

    Values.Apply;
  finally
    Values.Free;
  end;
end;

procedure TAHMSettingsManager.LoadAudioSettings;
var
  Values: TAHMMetaData;
  Prefs: TAHMPrefsManager;
begin
  // Load audio settings into meta data manager
  Prefs := ApplicationManagerInstance.PreferencesManager;
  Values := TAHMMetaData.Create;
  try
    // Sound effect settings is simple boolean flag
    Values.AddValue(META_AUD_SOUNDEFFECT, Prefs.SoundEffects);

    // Add sound effect volume metadata values
    Values.AddValue(META_EFFECT_VOLUME_MAX, IntToStr(DEF_SOUND_VOLUME));
    Values.AddValue(META_EFFECT_VOLUME, Prefs.SoundVolume);

    Values.Apply;
  finally
    Values.Free;
  end;
end;

procedure TAHMSettingsManager.LoadGeneralSettings;
var
  Themes: TStringList;
  Items: TAHMUIObjectList;
  Values: TAHMMetaData;
  i: Integer;
begin
  // Load general settings into meta data manager
  Values := TAHMMetaData.Create;
  try
    // Add list of installed themes and current theme
    Themes := ApplicationManagerInstance.ThemeManager.InstalledThemes;
    for i := 0 to Pred(Themes.Count) do
    begin
      Values.AddValue(META_GEN_THEMES + META_SEP + IntToStr(i), Themes[i]);
      if Themes[i] = ApplicationManagerInstance.ThemeManager.ThemeName then
        Values.AddValue(META_GEN_THEME, IntToStr(i));
    end;

    // Add list of available languages and current language
    Items := LanguageManagerInstance.Languages;
    for i := 0 to Pred(Items.Count) do
    begin
      Values.AddValue(META_GEN_LANGUAGES + META_SEP + IntToStr(i), Items[i].Name);
      if Items[i].Name = LanguageManagerInstance.CurrentLanguageName then
        Values.AddValue(META_GEN_LANGUAGE, IntToStr(i));
    end;

    Values.Apply;
  finally
    Values.Free;
  end;
end;

procedure TAHMSettingsManager.LoadSlideshowSettings;
var
  Values: TAHMMetaData;
  Prefs: TAHMPrefsManager;
begin
  // Load display settings into meta data manager
  Prefs := ApplicationManagerInstance.PreferencesManager;
  Values := TAHMMetaData.Create;
  try
    // Add list of slideshow delays - zero padded so sorted in right order
    Values.AddValue(META_SLIDE_DURATIONS + META_SEP + '00', META_MARKER + META_TEXT_BEG + 'system.slideshow.off' + META_TEXT_END);
    Values.AddValue(META_SLIDE_DURATIONS + META_SEP + '03', '3 ' + META_MARKER + META_TEXT_BEG + 'system.slideshow.seconds' + META_TEXT_END);
    Values.AddValue(META_SLIDE_DURATIONS + META_SEP + '05', '5 ' + META_MARKER + META_TEXT_BEG + 'system.slideshow.seconds' + META_TEXT_END);
    Values.AddValue(META_SLIDE_DURATIONS + META_SEP + '08', '8 ' + META_MARKER + META_TEXT_BEG + 'system.slideshow.seconds' + META_TEXT_END);
    Values.AddValue(META_SLIDE_DURATIONS + META_SEP + '10', '10 ' + META_MARKER + META_TEXT_BEG + 'system.slideshow.seconds' + META_TEXT_END);
    Values.AddValue(META_SLIDE_DURATIONS + META_SEP + '20', '20 ' + META_MARKER + META_TEXT_BEG + 'system.slideshow.seconds' + META_TEXT_END);
    Values.AddValue(META_SLIDE_DURATIONS + META_SEP + '30', '30 ' + META_MARKER + META_TEXT_BEG + 'system.slideshow.seconds' + META_TEXT_END);
    Values.AddValue(META_SLIDE_DURATION, Format('%.2d', [Prefs.SlideshowDelay]));

    // Other slideshow settings are simple boolean flags
    Values.AddValue(META_SLIDE_PANZOOM, Prefs.SlideshowPanZoom);
    Values.AddValue(META_SLIDE_FADING, Prefs.SlideshowFading);
    Values.AddValue(META_SLIDE_FULLIMAGE, Prefs.SlideshowBorders);

    Values.Apply;
  finally
    Values.Free;
  end;
end;

procedure TAHMSettingsManager.LoadThemeSettings;
begin
  // Load theme settings into metadata manager
  ApplicationManagerInstance.ThemeManager.ApplyThemeSettings;
end;

procedure TAHMSettingsManager.LoadVisualisationSettings;
var
  Values: TAHMMetaData;
  Prefs: TAHMPrefsManager;
begin
  // Load visualisation settings into meta data manager
  Prefs := ApplicationManagerInstance.PreferencesManager;
  Values := TAHMMetaData.Create;
  try
    // Add list of supported visualisation qualities and current quality
    Values.AddValue(META_VIS_QUALITIES + META_SEP + '0', META_MARKER + META_TEXT_BEG + 'system.visualisation.fastquality' + META_TEXT_END);
    Values.AddValue(META_VIS_QUALITIES + META_SEP + '1', META_MARKER + META_TEXT_BEG + 'system.visualisation.basicquality' + META_TEXT_END);
    Values.AddValue(META_VIS_QUALITIES + META_SEP + '2', META_MARKER + META_TEXT_BEG + 'system.visualisation.mediumquality' + META_TEXT_END);
    Values.AddValue(META_VIS_QUALITIES + META_SEP + '3', META_MARKER + META_TEXT_BEG + 'system.visualisation.goodquality' + META_TEXT_END);
    Values.AddValue(META_VIS_QUALITIES + META_SEP + '4', META_MARKER + META_TEXT_BEG + 'system.visualisation.highquality' + META_TEXT_END);
    Values.AddValue(META_VIS_QUALITIES + META_SEP + '5', META_MARKER + META_TEXT_BEG + 'system.visualisation.ultraquality' + META_TEXT_END);
    Values.AddValue(META_VIS_QUALITY, IntToStr(Prefs.VisualisationQuality));

    Values.Apply;
  finally
    Values.Free;
  end;
end;

procedure TAHMSettingsManager.LoadEqualiserSettings;
var
  i, Value: Integer;
  Prefix: String;
  Values: TAHMMetaData;
  Eq: TAHMEqualiserManager;
begin
  // Load equaliser settings into meta data manager
  Eq := ApplicationManagerInstance.MediaManager.Equaliser;
  Values := TAHMMetaData.Create;
  try
    // Add list of equaliser bands and current values
    for i := Low(TAHMEqualiserBands) to High(TAHMEqualiserBands) do
    begin
      Prefix := META_EQUALISER + META_SEP + IntToStr(i) + META_SEP;
      Value := Eq.CurrentEqualiser[i] - EQU_OFFSET;
      Values.AddValue(Prefix + META_EQU_VAL_SUFFIX, IntToStr(Value));
    end;

    // Add maximum value for all bands
    Values.AddValue(META_EQU_MAX_VALUE, IntToStr(EQU_MAX_VALUE));

    // Add bass boost metadata values
    Values.AddValue(META_BASS_MAX_VALUE, IntToStr(BASS_MAX_VALUE));
    Values.AddValue(META_BASS_VALUE, IntToStr(Eq.BassBoost));
    Values.AddValue(META_BASS_MAX_FREQ, IntToStr(BASS_MAX_FREQ));
    Values.AddValue(META_BASS_FREQ_VALUE, IntToStr(Eq.BassFrequency - BASS_MIN_FREQ));
    Values.AddValue(META_BASS_ENABLED, Eq.TrueBass);

    // Add treble boost metadata values
    Values.AddValue(META_TREBLE_MAX_VALUE, IntToStr(TREBLE_MAX_VALUE));
    Values.AddValue(META_TREBLE_VALUE, IntToStr(Eq.TrebleBoost));
    Values.AddValue(META_TREBLE_MAX_FREQ, IntToStr(TREBLE_MAX_FREQ));
    Values.AddValue(META_TREBLE_FREQ_VALUE, IntToStr(Eq.TrebleFrequency - TREBLE_MIN_FREQ));
    Values.AddValue(META_TREBLE_ENABLED, Eq.TrebleEnhance);

    // Add 3d sound metadata values
    Values.AddValue(META_SOUND3D_MAX_VALUE, IntToStr(SOUND3D_MAX_VALUE));
    Values.AddValue(META_SOUND3D_VALUE, IntToStr(Eq.Sound3DBoost));
    Values.AddValue(META_SOUND3D_ENABLED, Eq.Sound3D);

    Values.Apply;
  finally
    Values.Free;
  end;
end;

procedure TAHMSettingsManager.LoadMusicSettings;
var
  Values: TAHMMetaData;
  Prefs: TAHMPrefsManager;
begin
  // Load music settings into meta data manager
  Prefs := ApplicationManagerInstance.PreferencesManager;
  Values := TAHMMetaData.Create;
  try
    // Sound effect settings is simple boolean flag
    Values.AddValue(META_MUSIC_COMPILATION, Prefs.CompilationArtists);

    Values.Apply;
  finally
    Values.Free;
  end;
end;

procedure TAHMSettingsManager.SaveDisplaySettings;
var
  Mode: TAHMDisplayMode;
  Meta: TAHMMetaDataManager;
  Prefs: TAHMPrefsManager;
  Index: Integer;
  Restart, BoolVal: Boolean;
begin
  // Save display settings from meta data manager into preferences
  Prefs := ApplicationManagerInstance.PreferencesManager;
  Meta := ApplicationManagerInstance.MetaDataManager;
  Restart := False;

  Prefs.VideoThrottle := StrToIntDef(Meta.GetMetaValue(META_VIDEOTHROTTLE), DEF_VIDEO_THROTTLE);
  Prefs.ScreenSaverDelay := StrToIntDef(Meta.GetMetaValue(META_SCREENSAVER), DEF_SCRN_SAVER_DELAY);

  BoolVal := Meta.GetMetaBoolean(META_FULLSCREEN);
  if BoolVal <> Prefs.FullScreen then
  begin
    Prefs.FullScreen := BoolVal;
    Restart := True; // Restart required when we change fullscreen setting
  end;

  // Get selected display mode
  Index := StrToIntDef(Meta.GetMetaValue(META_SCREENSIZE), 0);
  Mode := ScreenInstance.DisplayModes.GetDisplayMode(Index);
  if Assigned(Mode) then
  begin
    if (Prefs.ScreenWidth <> Mode.Width) or (Prefs.ScreenHeight <> Mode.Height) then
    begin
      Prefs.ScreenWidth := Mode.Width;
      Prefs.ScreenHeight := Mode.Height;
      Restart := True; // Restart required when we change resolution setting
    end;
  end;

  // Update screensaver delay immediately. Other screen settings require a restart
  ApplicationManagerInstance.UIManager.ScreenSaver.ScreenSaverDelay := Prefs.ScreenSaverDelay;

  // Raise restart required event for UI to handle
  if Restart then ApplicationManagerInstance.ActionManager.ProcessAction(AC_NEEDRESTART);
end;

procedure TAHMSettingsManager.SavePositionSettings;
var
  Prefs: TAHMPrefsManager;
  Meta: TAHMMetaDataManager;
begin
  // Save position/scale settings from meta data manager into preferences
  Prefs := ApplicationManagerInstance.PreferencesManager;
  Meta := ApplicationManagerInstance.MetaDataManager;

  // Update current settings for screen offset & scale
  Prefs.ScreenXOffset := (Meta.GetMetaInteger(META_POS_XOFFSET) / Prefs.ScreenWidth) - 0.5;
  Prefs.ScreenYOffset := (Meta.GetMetaInteger(META_POS_YOFFSET) / Prefs.ScreenHeight) - 0.5;
  Prefs.ScreenXScale := (Meta.GetMetaInteger(META_POS_XSCALE) / Prefs.ScreenWidth) + 0.5;
  Prefs.ScreenYScale := (Meta.GetMetaInteger(META_POS_YSCALE) / Prefs.ScreenHeight) + 0.5;
  
  ApplicationManagerInstance.ConfigureScreenPosition;
end;

procedure TAHMSettingsManager.SaveAudioSettings;
var
  Meta: TAHMMetaDataManager;
  Prefs: TAHMPrefsManager;
begin
  // Save audio settings from meta data manager into preferences
  Prefs := ApplicationManagerInstance.PreferencesManager;
  Meta := ApplicationManagerInstance.MetaDataManager;

  Prefs.SoundEffects := Meta.GetMetaBoolean(META_AUD_SOUNDEFFECT);
  Prefs.SoundVolume := Meta.GetMetaInteger(META_EFFECT_VOLUME);
end;

procedure TAHMSettingsManager.SaveGeneralSettings;
var
  Meta: TAHMMetaDataManager;
  Prefs: TAHMPrefsManager;
  Value: String;
  Restart: Boolean;
begin
  // Save general settings from meta data manager into preferences
  Prefs := ApplicationManagerInstance.PreferencesManager;
  Meta := ApplicationManagerInstance.MetaDataManager;
  Restart := False;

  Value := Meta.GetMetaValue(META_GEN_LANGUAGE);
  Prefs.LanguageName := Meta.LookupMetaValue(Value, META_GEN_LANGUAGES);
  Value := Meta.GetMetaValue(META_GEN_THEME);
  Value := Meta.LookupMetaValue(Value, META_GEN_THEMES);
  if Value <> Prefs.ThemeName then
  begin
    Prefs.ThemeName := Value;
    Restart := True; // Restart required when we change theme
  end;

  // Update language immediately. Other general settings require a restart
  LanguageManagerInstance.CurrentLanguageName := Prefs.LanguageName;

  // Raise restart required event for UI to handle
  if Restart then ApplicationManagerInstance.ActionManager.ProcessAction(AC_NEEDRESTART);
end;

procedure TAHMSettingsManager.SaveSlideshowSettings;
var
  Meta: TAHMMetaDataManager;
  Prefs: TAHMPrefsManager;
begin
  // Save display settings from meta data manager into preferences
  Prefs := ApplicationManagerInstance.PreferencesManager;
  Meta := ApplicationManagerInstance.MetaDataManager;

  Prefs.SlideshowDelay := StrToIntDef(Meta.GetMetaValue(META_SLIDE_DURATION), DEF_SLIDESHOW_DELAY);
  Prefs.SlideshowPanZoom := Meta.GetMetaBoolean(META_SLIDE_PANZOOM);
  Prefs.SlideshowFading := Meta.GetMetaBoolean(META_SLIDE_FADING);
  Prefs.SlideshowBorders := Meta.GetMetaBoolean(META_SLIDE_FULLIMAGE);
end;

procedure TAHMSettingsManager.SaveThemeSettings;
begin
  // Save theme settings from metadata manager into theme
  ApplicationManagerInstance.ThemeManager.UpdateThemeSettings;
end;

procedure TAHMSettingsManager.SaveVisualisationSettings;
var
  Meta: TAHMMetaDataManager;
  Prefs: TAHMPrefsManager;
  Value: Integer;
begin
  // Save visualisation settings from meta data manager into preferences
  Prefs := ApplicationManagerInstance.PreferencesManager;
  Meta := ApplicationManagerInstance.MetaDataManager;

  Value := StrToIntDef(Meta.GetMetaValue(META_VIS_QUALITY), DEF_VIS_QUALITY);
  if Value <> Prefs.VisualisationQuality then
  begin
    Prefs.VisualisationQuality := Value;
    ApplicationManagerInstance.MediaManager.VisualisationQualityChanged;
  end;
end;

procedure TAHMSettingsManager.SaveEqualiserSettings;
var
  Prefix: String;
  i, Value: Integer;
  Eq: TAHMEqualiserManager;
  Meta: TAHMMetaDataManager;
begin
  // Save settings from metadata manager into equaliser manager
  Meta := ApplicationManagerInstance.MetaDataManager;
  Eq := ApplicationManagerInstance.MediaManager.Equaliser;

  // Read list of equaliser bands and current values
  for i := Low(TAHMEqualiserBands) to High(TAHMEqualiserBands) do
  begin
    Prefix := META_EQUALISER + META_SEP + IntToStr(i) + META_SEP;
    Value := Meta.GetMetaInteger(Prefix + META_EQU_VAL_SUFFIX);
    Eq.CurrentEqualiser[i] := Value + EQU_OFFSET;
  end;

  // Read bass boost values
  Eq.BassBoost := Meta.GetMetaInteger(META_BASS_VALUE);
  Eq.BassFrequency := Meta.GetMetaInteger(META_BASS_FREQ_VALUE) + BASS_MIN_FREQ;
  Eq.TrueBass := Meta.GetMetaBoolean(META_BASS_ENABLED);

  // Read treble boost values
  Eq.TrebleBoost := Meta.GetMetaInteger(META_TREBLE_VALUE);
  Eq.TrebleFrequency := Meta.GetMetaInteger(META_TREBLE_FREQ_VALUE) + TREBLE_MIN_FREQ;
  Eq.TrebleEnhance := Meta.GetMetaBoolean(META_TREBLE_ENABLED);

  // Read 3D effect values
  Eq.Sound3DBoost := Meta.GetMetaInteger(META_SOUND3D_VALUE);
  Eq.Sound3D := Meta.GetMetaBoolean(META_SOUND3D_ENABLED);

  // Notify media manager that equaliser settings have changed
  ApplicationManagerInstance.MediaManager.EqualiserSettingsChanged;
end;

procedure TAHMSettingsManager.SaveMusicSettings;
var
  Meta: TAHMMetaDataManager;
  Prefs: TAHMPrefsManager;
begin
  // Save music settings from meta data manager into preferences
  Prefs := ApplicationManagerInstance.PreferencesManager;
  Meta := ApplicationManagerInstance.MetaDataManager;

  Prefs.CompilationArtists := Meta.GetMetaBoolean(META_MUSIC_COMPILATION);
end;


end.
